/**
 * Copyright 1998-2006, CHISEL Group, University of Victoria, Victoria, BC, Canada.
 * All rights reserved.
 */
package ca.uvic.cs.cogz.mapping.filter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;

import ca.uvic.cs.cogz.mapping.filter.TreeFilterManager.TreeFilterType;
import ca.uvic.cs.cogz.util.TreeUtil;
import edu.stanford.smi.protege.model.Cls;
import edu.stanford.smi.protege.model.Frame;
import edu.stanford.smi.protege.model.KnowledgeBase;

/**
 * Implementation of a ITreeSearchBasedFilter. Used to find Frames in an ontology with a name that
 * matches given search text.
 * 
 * @author Sean Falconer
 * @date 10-Jan-07
 */
public class TreeSearchFilter implements ITreeSearchBasedFilter {
	private String searchText;
	private HashSet<Cls> searchResults;

	public TreeSearchFilter() {
		searchText = "";
		searchResults = new HashSet<Cls>();
	}

	public void setSearchText(String searchText) {
		if (searchText.endsWith("*")) {
			if (searchText.length() >= 2) {
				this.searchText = searchText.substring(0, searchText.length() - 1);
			} else {
				this.searchText = "";
			}
		} else {
			this.searchText = searchText;
		}
	}

	public String getSearchText() {
		return searchText;
	}

	public boolean isActive() {
		return searchText.length() > 0;
	}

	/**
	 * Using searchText, this method performs a search for all matching Cls object's in the given
	 * KnowledgeBase and returns a collection of object paths for each search hit.
	 */
	@SuppressWarnings("unchecked")
	public Collection<Collection> performSearch(KnowledgeBase kb) {
		//if(searchText.length() > 0) {
		String queryString = searchText;
		if (!queryString.endsWith("*")) {
			queryString += "*";
		}

		Collection<Cls> results = new HashSet(kb.getClsesWithMatchingBrowserText(queryString, Collections.EMPTY_LIST, Integer.MAX_VALUE));
		HashSet<Collection> matchedPaths = new HashSet<Collection>(results.size());

		searchResults.clear();

		for (Cls searchHit : results) {
			searchResults.addAll(searchHit.getSuperclasses());
			searchResults.addAll(searchHit.getSubclasses());
			ArrayList<Frame> currentPath = new ArrayList<Frame>();
			TreeUtil.buildObjectPaths(searchHit, currentPath, matchedPaths, true);
		}

		searchResults.addAll(results);

		return matchedPaths;
		//}
		//return null;
	}

	public boolean isMatch(Frame frame) {
		return isActive() && searchResults.contains(frame);
	}

	public void reset() {
		searchText = "";
		searchResults.clear();
	}

	public TreeFilterType getType() {
		return TreeFilterType.TREE_SEARCH_FILTER;
	}
}
